package shop_cart

import (
	"context"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"mxshop-api/order-web/api"
	"mxshop-api/order-web/forms/request"
	"mxshop-api/order-web/global"
	"mxshop-api/order-web/proto"
	"net/http"
	"strconv"
)

/*
*
添加到购物车
*/
func New(ctx *gin.Context) {
	//1 校验参数
	shopCartItemForm := request.ShopCartItemForm{}
	if err := ctx.ShouldBindJSON(&shopCartItemForm); err != nil {
		zap.S().Errorf("添加到购物车,参数接收异常:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	//2 检查商品是否存在
	goodsId := shopCartItemForm.GoodsId
	nums := shopCartItemForm.Nums
	if _, err := global.GoodsSrvClient.GetGoodsDetail(context.Background(), &proto.GoodInfoRequest{Id: goodsId}); err != nil {
		zap.S().Errorf("添加到购物车,选择商品查询失败:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	//3 判断库存是否满足
	inventoryDetail, err := global.InventorySrvClient.InvDetail(context.Background(), &proto.GoodsInvInfo{
		GoodsId: goodsId,
		Num:     nums,
	})
	if err != nil {
		zap.S().Errorf("添加到购物车,选择商品库存失败:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	if inventoryDetail.Num < nums {
		zap.S().Error("添加到购物车,商品库存不足")
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg": "商品库存不足",
		})
		return
	}

	//4 添加到购物车
	userId, _ := ctx.Get("userId")
	item, err := global.OrderSrvClient.CreateCartItem(context.Background(), &proto.CartItemRequest{
		UserId:  int32(userId.(uint)), //强制转int32(userId.(uint))
		GoodsId: goodsId,
		Nums:    nums,
	})
	if err != nil {
		zap.S().Errorf("添加到购物车失败:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"id":  item.Id,
		"msg": "添加购物车成功",
	})
}

/*
*
修改购物车
*/
func Update(ctx *gin.Context) {
	//1 判断url格式
	idStr := ctx.Param("id") //这个id就是goodsId
	id, err := strconv.Atoi(idStr)
	if err != nil {
		zap.S().Errorf("请求url格式不正确")
		ctx.JSON(http.StatusOK, gin.H{
			"msg": "请求url格式不正确",
		})
		return
	}
	//2 获取请求参数
	updateForm := request.ShopCartItemUpdateForm{}
	err = ctx.ShouldBindJSON(&updateForm)
	if err != nil {
		zap.S().Errorf("更新购物车,参数接收异常:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	//3 请求server更新购物车
	userId, _ := ctx.Get("userId")
	checked := updateForm.Checked
	nums := updateForm.Nums
	_, err = global.OrderSrvClient.UpdateCartItem(context.Background(), &proto.CartItemRequest{
		UserId:  int32(userId.(uint)),
		GoodsId: int32(id),
		Checked: *checked,
		Nums:    nums,
	})
	if err != nil {
		zap.S().Errorf("更新购物车请求是不:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.Status(http.StatusOK)
}

/*
*
购物车列表
*/
func List(ctx *gin.Context) {
	//1 查询购物车列表
	userId, _ := ctx.Get("userId")
	resp := gin.H{
		"total": 0,
		"data":  nil,
	}
	//list, err := global.OrderSrvClient.CartItemList(context.Background(), &proto.UserInfo{Id: int32(userId.(uint))})
	list, err := global.OrderSrvClient.CartItemList(context.WithValue(context.Background(), "ginContext", ctx), &proto.UserInfo{Id: int32(userId.(uint))})
	if err != nil {
		zap.S().Errorf("获取购物车商品失败:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	resp["total"] = list.Total
	ids := make([]int32, 0)
	for _, info := range list.Data {
		ids = append(ids, info.GoodsId)
	}
	//2 查询购物车中的商品信息
	goods, err := global.GoodsSrvClient.BatchGetGoods(context.Background(), &proto.BatchGoodsIdInfo{Id: ids})
	if err != nil {
		zap.S().Errorf("获取购物车商品详情失败:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	goodsMap := map[int32]*proto.GoodsInfoResponse{}
	for _, good := range goods.Data {
		goodsMap[good.Id] = good
	}
	//3 拼接返回数据
	dataList := make([]interface{}, 0)
	for _, data := range list.Data {
		tmpData := map[string]interface{}{}
		tmpData["id"] = data.Id
		tmpData["goods_id"] = data.GoodsId
		tmpData["good_name"] = goodsMap[data.GoodsId].Name
		tmpData["goods_image"] = goodsMap[data.GoodsId].GoodsFrontImage
		tmpData["good_price"] = goodsMap[data.GoodsId].ShopPrice
		tmpData["nums"] = data.Nums
		tmpData["checked"] = data.Checked
		dataList = append(dataList, tmpData)
	}
	resp["data"] = dataList
	ctx.JSON(http.StatusOK, resp)
}

/*
*
删除购物车
*/
func Delete(ctx *gin.Context) {
	//1 判断url格式
	idStr := ctx.Param("id") //这个id就是goodsId
	id, err := strconv.Atoi(idStr)
	if err != nil {
		zap.S().Errorf("请求url格式不正确")
		ctx.JSON(http.StatusOK, gin.H{
			"msg": "请求url格式不正确",
		})
		return
	}
	//3 请求server更新购物车
	userId, _ := ctx.Get("userId")
	_, err = global.OrderSrvClient.DeleteCartItem(context.Background(), &proto.CartItemRequest{
		UserId:  int32(userId.(uint)),
		GoodsId: int32(id),
	})
	if err != nil {
		zap.S().Errorf("删除购物车商品失败:%v", err)
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.Status(http.StatusOK)
}
